using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Mark.Data;
using Mark.Models;
using Mark.Services.Interfaces;
using MarkFileInfo = Mark.Models.FileInfo;

namespace Mark.Services;

/// <summary>
/// 聊天服务实现
/// </summary>
public class ChatService : IChatService
{
    private readonly MarkDbContext _context;
    private readonly ILogger<ChatService> _logger;

    public ChatService(MarkDbContext context, ILogger<ChatService> logger)
    {
        _context = context;
        _logger = logger;
    }

    #region 对话管理

    public async Task<Conversation> CreateConversationAsync(string userId, string title, string? description = null)
    {
        var conversation = new Conversation
        {
            UserId = userId,
            Title = title,
            Description = description,
            Status = "Active",
            LastActivityAt = DateTime.UtcNow
        };

        _context.Conversations.Add(conversation);
        await _context.SaveChangesAsync();

        _logger.LogInformation($"Created conversation {conversation.Id} for user {userId}");
        return conversation;
    }

    public async Task<Conversation?> GetConversationAsync(string conversationId)
    {
        return await _context.Conversations
            .Include(c => c.User)
            .Include(c => c.Messages.OrderBy(m => m.CreatedAt))
                .ThenInclude(m => m.Model)
            .FirstOrDefaultAsync(c => c.Id == conversationId && !c.IsDeleted);
    }

    public async Task<IEnumerable<Conversation>> GetUserConversationsAsync(string userId)
    {
        return await _context.Conversations
            .Where(c => c.UserId == userId && !c.IsDeleted)
            .OrderByDescending(c => c.LastActivityAt)
            .ToListAsync();
    }

    public async Task<bool> UpdateConversationAsync(string conversationId, string title, string? description = null)
    {
        var conversation = await _context.Conversations
            .FirstOrDefaultAsync(c => c.Id == conversationId && !c.IsDeleted);

        if (conversation == null) return false;

        conversation.Title = title;
        conversation.Description = description;
        conversation.UpdatedAt = DateTime.UtcNow;

        await _context.SaveChangesAsync();
        return true;
    }

    public async Task<bool> DeleteConversationAsync(string conversationId)
    {
        var conversation = await _context.Conversations
            .FirstOrDefaultAsync(c => c.Id == conversationId && !c.IsDeleted);

        if (conversation == null) return false;

        conversation.IsDeleted = true;
        conversation.UpdatedAt = DateTime.UtcNow;

        await _context.SaveChangesAsync();
        return true;
    }

    #endregion

    #region 消息管理

    public async Task<Message> SendMessageAsync(string conversationId, string content, string role = "user", string? modelId = null)
    {
        var conversation = await _context.Conversations
            .FirstOrDefaultAsync(c => c.Id == conversationId && !c.IsDeleted);

        if (conversation == null)
            throw new ArgumentException("Conversation not found");

        var lastMessage = await _context.Messages
            .Where(m => m.ConversationId == conversationId)
            .OrderByDescending(m => m.SequenceNumber)
            .FirstOrDefaultAsync();

        var message = new Message
        {
            ConversationId = conversationId,
            Content = content,
            Role = role,
            ModelId = modelId,
            SequenceNumber = (lastMessage?.SequenceNumber ?? 0) + 1,
            Status = "sent"
        };

        _context.Messages.Add(message);

        // 更新对话活动时间和消息计数
        conversation.LastActivityAt = DateTime.UtcNow;
        conversation.MessageCount++;

        await _context.SaveChangesAsync();

        _logger.LogInformation($"Sent message {message.Id} in conversation {conversationId}");
        return message;
    }

    public async Task<Message?> GetMessageAsync(string messageId)
    {
        return await _context.Messages
            .Include(m => m.Conversation)
            .Include(m => m.Model)
            .Include(m => m.MessageFiles)
                .ThenInclude(mf => mf.FileInfo)
            .FirstOrDefaultAsync(m => m.Id == messageId && !m.IsDeleted);
    }

    public async Task<IEnumerable<Message>> GetConversationMessagesAsync(string conversationId)
    {
        return await _context.Messages
            .Where(m => m.ConversationId == conversationId && !m.IsDeleted)
            .Include(m => m.Model)
            .Include(m => m.MessageFiles)
                .ThenInclude(mf => mf.FileInfo)
            .OrderBy(m => m.SequenceNumber)
            .ToListAsync();
    }

    public async Task<bool> UpdateMessageAsync(string messageId, string content)
    {
        var message = await _context.Messages
            .FirstOrDefaultAsync(m => m.Id == messageId && !m.IsDeleted);

        if (message == null) return false;

        message.Content = content;
        message.UpdatedAt = DateTime.UtcNow;

        await _context.SaveChangesAsync();
        return true;
    }

    public async Task<bool> DeleteMessageAsync(string messageId)
    {
        var message = await _context.Messages
            .FirstOrDefaultAsync(m => m.Id == messageId && !m.IsDeleted);

        if (message == null) return false;

        message.IsDeleted = true;
        message.UpdatedAt = DateTime.UtcNow;

        await _context.SaveChangesAsync();
        return true;
    }

    #endregion

    #region AI 响应生成

    public async Task<Message> GenerateResponseAsync(string conversationId, string modelId)
    {
        var model = await _context.Models
            .Include(m => m.Provider)
            .FirstOrDefaultAsync(m => m.Id == modelId && m.Status == "Active");

        if (model == null)
            throw new ArgumentException("Model not found or inactive");

        // 获取对话历史
        var messages = await GetConversationMessagesAsync(conversationId);
        
        // 这里应该调用实际的AI服务，暂时返回示例响应
        var responseContent = await CallAIService(model, messages.ToList());

        var response = await SendMessageAsync(conversationId, responseContent, "assistant", modelId);
        
        _logger.LogInformation($"Generated AI response {response.Id} using model {modelId}");
        return response;
    }

    private async Task<string> CallAIService(Model model, List<Message> messages)
    {
        // TODO: 实现实际的AI服务调用
        // 这里可以集成OpenAI、DeepSeek、Claude等AI服务
        await Task.Delay(1000); // 模拟API调用延迟
        return "这是AI生成的响应内容。";
    }

    #endregion

    #region 文件管理

    public async Task<MarkFileInfo> UploadFileAsync(string userId, Stream fileStream, string fileName, string mimeType)
    {
        // 生成文件存储路径
        var fileId = Guid.NewGuid().ToString();
        var fileExtension = Path.GetExtension(fileName);
        var storagePath = Path.Combine("uploads", userId, $"{fileId}{fileExtension}");
        
        // 确保目录存在
        var directory = Path.GetDirectoryName(storagePath);
        if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
        {
            Directory.CreateDirectory(directory);
        }

        // 保存文件
        using (var fileStreamOut = new FileStream(storagePath, FileMode.Create))
        {
            await fileStream.CopyToAsync(fileStreamOut);
        }

        // 计算文件大小
        var fileInfo = new System.IO.FileInfo(storagePath);

        var markFileInfo = new MarkFileInfo
        {
            Name = fileName,
            Path = storagePath,
            Size = fileInfo.Length,
            MimeType = mimeType,
            Extension = fileExtension,
            UserId = userId,
            LastModified = DateTime.UtcNow,
            Status = "uploaded"
        };

        _context.FileInfos.Add(markFileInfo);
        await _context.SaveChangesAsync();

        _logger.LogInformation($"Uploaded file {markFileInfo.Id} for user {userId}");
        return markFileInfo;
    }

    public async Task<bool> AttachFileToMessageAsync(string messageId, string fileInfoId, string role = "attachment")
    {
        var message = await _context.Messages
            .FirstOrDefaultAsync(m => m.Id == messageId && !m.IsDeleted);

        var fileInfo = await _context.FileInfos
            .FirstOrDefaultAsync(f => f.Id == fileInfoId && !f.IsDeleted);

        if (message == null || fileInfo == null) return false;

        var messageFile = new MessageFile
        {
            MessageId = messageId,
            FileInfoId = fileInfoId,
            Role = role
        };

        _context.MessageFiles.Add(messageFile);
        await _context.SaveChangesAsync();

        return true;
    }

    public async Task<IEnumerable<MarkFileInfo>> GetMessageFilesAsync(string messageId)
    {
        return await _context.MessageFiles
            .Where(mf => mf.MessageId == messageId && !mf.IsDeleted)
            .Include(mf => mf.FileInfo)
            .Select(mf => mf.FileInfo)
            .ToListAsync();
    }

    #endregion
} 